import "reflect-metadata";
import loaderAllRouter from "../common/loaderRouter";
import Router from "koa-router";
import Koa, { Context } from "koa";
type MethodType = "get" | "post" | "put" | "delete";

export const Controller = (modulePath: string = "/") => {
  const router = new Router();
  // 判断二级路由是否存在
  if (modulePath) {
    // 判断是否>1
    if (modulePath.length > 0) {
      // 判断是否写/
      if (!modulePath.startsWith("/")) {
        // 如果没写就给他加上
        modulePath = `/${modulePath}`;
      } else if (modulePath === "/") {
        // 如果只传了一个/就给他去掉
        modulePath = "";
      }
    }
    // 定义二级路由
    router.prefix(modulePath);
  }
  return (target: { new(...arg: any): any }) => { 
    // target 就是类本身，使用装饰器的类
    // methodname 是类里面的所有方法函数名
    let actionList = Object.getOwnPropertyDescriptors(target.prototype); // 获取类中的所有方法
    
    // 从原型对象上获取get装饰器上传到原型对象的函数方法
    for (let key in actionList) {
      // 遍历类里的所有方法，把constructor去掉
      if (key !== "constructor") { 
        // 获取根路由        
        const rootRouter = loaderAllRouter.app.context.rootRouter; 
        // 根据方法名获取具体的方法
        const routerHandlerFn = actionList[key].value;
        // 获取类里面@get定义的请求path
        const path: string = Reflect.getMetadata("path", target.prototype, key);
        // 获取类里面@get定义的请求方法
        const reqMethod: MethodType = Reflect.getMetadata("methodType", target.prototype, key);
        // 判断path和reqMethod是否存在
        if (path && reqMethod) {
          // 定义路由处理函数，传入上下文对象，执行类里面的方法，返回路由函数的结果
          const fn = async (ctx: Context) => {
            ctx.body = await routerHandlerFn(ctx);
          }
          router[reqMethod](path, fn) // 注册路由
          rootRouter.use(router.routes()); // 注册到一级路由
        }
        
      }
    }
  }
}